package com.gitee.qdbp.general.common.biz.files.service.wantu;

import java.io.File;
import java.io.InputStream;
import com.alibaba.media.MediaConfiguration;
import com.alibaba.media.MediaDir;
import com.alibaba.media.MediaFile;
import com.alibaba.media.MultiScanResult;
import com.alibaba.media.Result;
import com.alibaba.media.client.MediaClient;
import com.alibaba.media.common.PagedList;
import com.alibaba.media.manage.FileResource;
import com.alibaba.media.manage.GlobalFileResource;
import com.alibaba.media.manage.ManageClient;
import com.alibaba.media.manage.MediaEncodeRequest;
import com.alibaba.media.manage.MediaEncodeTask;
import com.alibaba.media.manage.PornFeedback;
import com.alibaba.media.manage.SnapshotRequest;
import com.alibaba.media.upload.BaseUploadRequest;
import com.alibaba.media.upload.MultipartCancelRequest;
import com.alibaba.media.upload.MultipartCompleteRequest;
import com.alibaba.media.upload.MultipartCompleteResponse;
import com.alibaba.media.upload.MultipartInitRequest;
import com.alibaba.media.upload.MultipartInitResponse;
import com.alibaba.media.upload.MultipartUploadRequest;
import com.alibaba.media.upload.MultipartUploadResponse;
import com.alibaba.media.upload.UploadClient;
import com.alibaba.media.upload.UploadPolicy;
import com.alibaba.media.upload.UploadRequest;
import com.alibaba.media.upload.UploadResponse;
import com.alibaba.media.upload.UploadTokenClient;

// copy form DefaultMediaClient
// 通过MediaClientFactory生成内部成员对象
public class SimpleMediaClient implements MediaClient {

    private MediaConfiguration configuration;

    private UploadTokenClient tokenClient;
    private UploadClient uploadClient;
    private ManageClient manageClient;

    private UploadPolicy defaultUploadPolicy;

    public SimpleMediaClient(MediaClientFactory factory) {
        configuration = factory.getConfiguration();
        tokenClient = factory.getTokenClient();
        uploadClient = factory.getUploadClient();
        manageClient = factory.getManageClient();
        defaultUploadPolicy = factory.getUploadPolicy();
    }

    @Override
    public Result<MediaFile> upload(String dir, String name, File file) {
        UploadRequest req = new UploadRequest(getUploadPolicy());
        req.setDir(dir);
        req.setName(name);
        req.setFile(file);
        Result<UploadResponse> r = upload(req);
        UploadResponse resp = r.getData();

        if (!r.isSuccess()) {
            return Result.create(r.getHttpStatus(), r.getRequestId(), r.getCode(), r.getMessage());
        }

        MediaFile mf = new MediaFile();
        mf.setDir(resp.getDir());
        mf.setName(resp.getName());
        mf.setMd5(resp.geteTag());
        mf.setMimeType(resp.getMimeType());
        mf.setSize(resp.getFileSize());
        mf.setCreateDate(resp.getFileModified());
        mf.setModifyDate(resp.getFileModified());
        mf.setUrl(resp.getUrl());
        return Result.create(r.getHttpStatus(), mf);
    }

    @Override
    public Result<MediaFile> upload(String dir, String name, InputStream input, long size) {
        UploadRequest req = new UploadRequest(getUploadPolicy());
        req.setDir(dir);
        req.setName(name);
        req.setInputStream(input, size);
        Result<UploadResponse> r = upload(req);
        UploadResponse resp = r.getData();

        if (!r.isSuccess()) {
            return Result.create(r.getHttpStatus(), r.getRequestId(), r.getCode(), r.getMessage());
        }

        MediaFile mf = new MediaFile();
        mf.setDir(resp.getDir());
        mf.setName(resp.getName());
        mf.setMd5(resp.geteTag());
        mf.setMimeType(resp.getMimeType());
        mf.setSize(resp.getFileSize());
        mf.setCreateDate(resp.getFileModified());
        mf.setModifyDate(resp.getFileModified());
        mf.setUrl(resp.getUrl());
        return Result.create(r.getHttpStatus(), mf);
    }

    @Override
    public Result<UploadResponse> upload(UploadRequest req) {
        setUploadToken(req);
        return uploadClient.upload(req);
    }

    @Override
    public Result<MultipartInitResponse> multipartInit(MultipartInitRequest req) {
        setUploadToken(req);
        return uploadClient.multipartInit(req);
    }

    @Override
    public Result<MultipartUploadResponse> multipartUpload(MultipartUploadRequest req) {
        setUploadToken(req);
        return uploadClient.multipartUpload(req);
    }

    @Override
    public Result<MultipartCompleteResponse> multipartComplete(MultipartCompleteRequest req) {
        setUploadToken(req);
        return uploadClient.multipartComplete(req);
    }

    @Override
    public Result<Void> multipartCancel(MultipartCancelRequest req) {
        setUploadToken(req);
        return uploadClient.multipartCancel(req);
    }

    @Override
    public Result<Boolean> existsFile(String dir, String name) {
        return manageClient.existsFile(dir, name);
    }

    @Override
    public Result<PagedList<MediaFile>> listFiles(String dir, int page, int pageSize) {
        return manageClient.listFiles(dir, page, pageSize);
    }

    @Override
    public Result<MediaFile> getFile(String dir, String name) {
        return manageClient.getFile(dir, name);
    }

    @Override
    public Result<Void> deleteFile(String dir, String name) {
        return manageClient.deleteFile(dir, name);
    }

    @Override
    public Result<Void> createDir(String dir) {
        return manageClient.createDir(dir);
    }

    @Override
    public Result<Boolean> existsDir(String dir) {
        return manageClient.existsDir(dir);
    }

    @Override
    public Result<PagedList<MediaDir>> listDirs(String dir, int page, int pageSize) {
        return manageClient.listDirs(dir, page, pageSize);
    }

    @Override
    public Result<Void> deleteDir(String dir) {
        return manageClient.deleteDir(dir);
    }

    @Override
    public Result<String> mediaEncode(MediaEncodeRequest mediaEncodeRequest) {
        return manageClient.mediaEncode(mediaEncodeRequest);
    }

    @Override
    public Result<MediaEncodeTask> getMediaEncodeResult(String mediaEncodeTaskId) {
        return manageClient.getMediaEncodeResult(mediaEncodeTaskId);
    }

    @Override
    public Result<MultiScanResult> scanPorn(FileResource... resources) {
        return manageClient.scanPorn(resources);
    }

    @Override
    public Result<MultiScanResult> scanPorn(GlobalFileResource... resources) {
        return manageClient.scanPorn(resources);
    }

    @Override
    public Result<MultiScanResult> scanAdvertising(FileResource... resources) {
        return manageClient.scanAdvertising(resources);
    }

    @Override
    public Result<MultiScanResult> scanAdvertising(GlobalFileResource... resources) {
        return manageClient.scanAdvertising(resources);
    }

    @Override
    public Result<Void> feedBack(PornFeedback... feedbacks) {
        return manageClient.feedBack(feedbacks);
    }

    @Override
    public Result<String> snapshot(SnapshotRequest request) {
        return manageClient.snapshot(request);
    }

    @Override
    public Result<Void> getSnapshotResult(String taskId) {
        return manageClient.getSnapshotResult(taskId);
    }

    @Override
    public Result<Void> fetch(String from, GlobalFileResource to) {
        return manageClient.fetch(from, to);
    }

    @Override
    public Result<Void> asyncFetch(String from, GlobalFileResource to) {
        return manageClient.asyncFetch(from, to);
    }

    @Override
    public Result<String> generateSignedUrl(String domain, String uri, String signedKey, Long expired) {
        return manageClient.generateSignedUrl(domain, uri, signedKey, expired);
    }

    @Override
    public void setTraceOn(boolean traceOn) {
        this.uploadClient.setTraceOn(traceOn);
    }

    private void setUploadToken(BaseUploadRequest req) {
        if (req.getToken() == null) {
            req.setToken(tokenClient.getUploadToken(getUploadPolicy(req)));
        }
    }

    protected UploadPolicy getUploadPolicy(BaseUploadRequest req) {
        UploadPolicy uploadPolicy = req.getUploadPolicy() != null ? req.getUploadPolicy() : getUploadPolicy();
        uploadPolicy.setNamespace(configuration.getNamespace());
        return uploadPolicy;
    }

    public ManageClient getManageClient() {
        return this.manageClient;
    }

    public UploadPolicy getUploadPolicy() {
        return this.defaultUploadPolicy;
    }

    public UploadTokenClient getUploadTokenClient() {
        return tokenClient;
    }
}
